<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div>
    <h2>一、事件与事件流</h2>
    <div>事件流都会经历三个阶段</div>
    <ul>
      <li>事件捕获阶段(capture phase)</li>
      <li>处于目标阶段(target phase)</li>
      <li>事件冒泡阶段(bubbling phase)</li>
    </ul>
  </div>
  <div><button id="clickMe">Click Me</button></div>
  <script>
    // 事件冒泡是一种从下往上的传播方式，由最具体的元素（触发节点）然后逐渐向上传播到最不具体的那个节点，也就是DOM中最高层的父节点
    var button = document.getElementById('clickMe');

    button.onclick = function () {
      console.log('1.Button');
    };
    document.body.onclick = function () {
      console.log('2.body');
    };
    document.onclick = function () {
      console.log('3.document');
    };
    window.onclick = function () {
      console.log('4.window');
    };
  </script>
  <div>
    <h2>二、事件模型</h2>
    <h4>事件模型可以分为三种：</h4>
    <ul>
      <li>原始事件模型（DOM0级）</li>
      <li>标准事件模型（DOM2级）</li>
      <li>IE事件模型（基本不用）</li>
    </ul>
  </div>
  <div><input class="btn" type="button" onclick="fun()"></div>
  <script>
    // 1.原始事件模型
    // <1>:通过标签绑定
    // <2>:通过获取dom绑定    如下，当希望为同一个元素绑定多个同类型事件的时候（上面的这个btn元素绑定2个点击事件），是不被允许的，后绑定的事件会覆盖之前的事件
    var btn = document.getElementsByClassName('.btn');
    btn.onclick = fun();

    function fun(){
      console.log('fun');
    }

    // 2.标准事件模型 可以在一个DOM元素上绑定多个事件处理器，各自并不会冲突
    // 在该事件模型中，一次事件共有三个过程:
    // 事件捕获阶段：事件从document一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数，如果有则执行
    // 事件处理阶段：事件到达目标元素, 触发目标元素的监听函数
    // 事件冒泡阶段：事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数，如果有则执行

    // 绑定：addEventListener(eventType, handler, useCapture)
    // 移出：removeEventListener(eventType, handler, useCapture)

    // 参数如下：
    // eventType指定事件类型(不要加on)
    // handler是事件处理函数
    // useCapture是一个boolean用于指定是否在捕获阶段进行处理，一般设置为false与IE浏览器保持一致
  </script>
    <div id='div'>
        <p id='p'>
            <span id='span'>Click Me!</span>
        </p>
    </div>
    <script>
      var div = document.getElementById('div');
      var p = document.getElementById('p');

      function onClickFn (event) {
          var tagName = event.currentTarget.tagName;
          var phase = event.eventPhase;
          console.log(tagName, phase);
      }
      // 第三个参数true代表冒泡阶段，false代表捕获阶段
      div.addEventListener('click', onClickFn, false);
      p.addEventListener('click', onClickFn, false);
      // 上述使用了eventPhase，返回一个代表当前执行阶段的整数值。1为捕获阶段、2为事件对象触发阶段、3为冒泡阶段

      // IE事件模型
      // 绑定：attachEvent(eventType, handler)
      // 移出：detachEvent(eventType, handler)
    </script>
</body>

</html>